package com.william.jdbcplus.core.generator.meta;

import com.william.jdbcplus.common.enums.IdType;
import com.william.jdbcplus.core.toolkit.SqlTypeConvertUtil;
import com.william.jdbcplus.core.toolkit.StringPool;
import com.william.jdbcplus.core.toolkit.StringUtil;
import com.william.jdbcplus.core.toolkit.WordUtils;
import com.william.jdbcplus.core.util.datameta.TableMetaColumnInfo;
import com.william.jdbcplus.core.util.datameta.TableMetaIndexInfo;
import com.william.jdbcplus.core.util.datameta.TableMetaInfo;
import com.william.jdbcplus.core.util.datameta.TableMetaPkInfo;

import java.util.ArrayList;
import java.util.List;

public class TableToEntityUtil {
    public static EntityTableInfo convert(TableMetaInfo tableInfo) {
        return convert(tableInfo, StringPool.EMPTY);
    }

    public static EntityTableInfo convert(TableMetaInfo tableInfo, String tablePrefix) {
        String entityName = tableToJava(tableInfo.getTableName(), tablePrefix);
        String tableName = tableInfo.getTableName().toLowerCase();
        String tableRemarks = tableInfo.getTableRemarks();
        List<TableMetaColumnInfo> columnList = tableInfo.getColumnList();
        TableMetaColumnInfo pkColumn = null;
        EntityTableKeyInfo tableKeyInfo = null;
        String primaryKeyName = "";
        if (tableInfo.getPkList() != null && tableInfo.getPkList().size() > 0) {
            TableMetaPkInfo tablePkInfo = tableInfo.getPkList().get(0);
            pkColumn = columnList.stream().filter(e -> e.getColumnName() != null && e.getColumnName().equals(tablePkInfo.getColumnName())).findFirst().orElse(null);
            primaryKeyName = tablePkInfo.getPkName();
        }

        if (pkColumn != null) {
            tableKeyInfo = EntityTableKeyInfo.builder()
                    .primaryKey(primaryKeyName)
                    .columnName(pkColumn.getColumnName())
                    .lowerColumnName(pkColumn.getColumnName().toLowerCase())
                    .attrType(SqlTypeConvertUtil.sqlTypeToJavaType(pkColumn.getDataType(), pkColumn).getSimpleName())
                    .size(pkColumn.getColumnSize())
                    .caseAttrName(columnToJava(pkColumn.getColumnName()))
                    .lowerAttrName(StringUtil.uncapitalize(columnToJava(pkColumn.getColumnName())))
                    .remarks(pkColumn.getColumnRemarks())
                    .type(SqlTypeConvertUtil.sqlTypeToJavaType(pkColumn.getDataType(), pkColumn).getSimpleName().equals("String") ? IdType.GUID : IdType.NUMBER)
                    .build();
        }

        List<EntityTableColumnInfo> entityList = new ArrayList<>();
        for (TableMetaColumnInfo item : columnList) {
            if (pkColumn != null && item.getColumnName().equals(pkColumn.getColumnName())) {
                continue;
            }
            TableMetaIndexInfo indexInfo = tableInfo.getIndexList().stream().filter(e -> item.getColumnName() != null && item.getColumnName().equals(e.getColumnName())).findFirst().orElse(null);
            if (indexInfo != null) {
                EntityTableColumnInfo entityColumn = EntityTableColumnInfo.builder()
                        .columnName(item.getColumnName())
                        .lowerColumnName(item.getColumnName().toLowerCase())
                        .attrType(SqlTypeConvertUtil.sqlTypeToJavaType(item.getDataType(), item).getSimpleName())
                        .size(item.getColumnSize())
                        .caseAttrName(columnToJava(item.getColumnName()))
                        .lowerAttrName(StringUtil.uncapitalize(columnToJava(item.getColumnName())))
                        .remarks(item.getColumnRemarks())
                        .digits(item.getDecimalDigits())
                        .nullable(item.getNullAble())
                        .hasIndex(true)
                        .indexName(indexInfo.getIndexName())
                        .isUnique(!indexInfo.getNonUnique())
                        .build();
                entityList.add(entityColumn);
            } else {
                EntityTableColumnInfo entityColumn = EntityTableColumnInfo.builder()
                        .columnName(item.getColumnName())
                        .lowerColumnName(item.getColumnName().toLowerCase())
                        .attrType(SqlTypeConvertUtil.sqlTypeToJavaType(item.getDataType(), item).getSimpleName())
                        .size(item.getColumnSize())
                        .caseAttrName(columnToJava(item.getColumnName()))
                        .lowerAttrName(StringUtil.uncapitalize(columnToJava(item.getColumnName())))
                        .digits(item.getDecimalDigits())
                        .nullable(item.getNullAble())
                        .remarks(item.getColumnRemarks())
                        .hasIndex(false)
                        .build();
                entityList.add(entityColumn);
            }
        }

        EntityTableInfo entityTableInfo = EntityTableInfo.builder()
                .entityName(entityName)
                .tableName(tableName)
                .tableRemarks(tableRemarks)
                .columnList(entityList)
                .keyInfo(tableKeyInfo)
                .build();

        return entityTableInfo;
    }


    /**
     * 表名转换成Java类名
     */
    public static String tableToJava(String tableName, String tablePrefix) {
        if (StringUtil.isNotBlank(tablePrefix) && tableName.startsWith(tablePrefix)) {
            tableName = tableName.replace(tablePrefix, "");
        }
        return columnToJava(tableName);
    }

    /**
     * 列名转换成Java属性名
     */
    public static String columnToJava(String columnName) {
        return WordUtils.capitalizeFully(columnName, new char[]{'_'}).replace("_", "");
    }
}
